
#include "log_warper.h"
#include <iostream>
namespace loging
{

static const	std::string	g_crlf="\r\n";
static const	std::string g_str_spliter="|";
const	char*	LOG_LVL_NAME[ll_end_palce_]=
{"DEBUG ","INFO  ","WARN  ","ERROR ","FATAL "};

class loger
{
public:

	loger()
	{}

	virtual	~loger(void)
	{
		finish();
		if(die_) ::abort ();
	}

	explicit	loger(loging_level log_lvl):die_(false)
	{
		prepare(log_lvl,"","",-1);
	}
	loger(loging_level log_lvl,const std::string& source_file,const std::string& func_name,int line_number,int error_code):die_(false)
	{
		prepare(log_lvl,source_file,func_name,line_number);
		get_ostream()<<"e_code="<<error_code;
	}
	loger(loging_level log_lvl,const std::string& source_file,const std::string& func_name,int line_number,bool abort):die_(abort)
	{prepare(log_lvl,source_file,func_name,line_number);}

	loger&		reset(loging_level log_lvl,const std::string& source_file,const std::string& func_name,int line_number)
	{
		ostream_.clear();
		ostream_.str ("");
		prepare(log_lvl,source_file,func_name,line_number);
		return *this;
	}
	void		prepare(loging_level log_lvl,const std::string& source_file,const std::string& func_name,int line_number)
	{
		ostream_<< LOG_LVL_NAME[log_lvl]<<g_str_spliter;
		if (source_file.length() + func_name.length() > 0){
			ostream_<<"S="<<source_file<<g_str_spliter
				<<"F="<<func_name<<g_str_spliter
				<<"L="<<line_number<<g_str_spliter;
		}
	}
	virtual	void		finish()
	{
		ostream_<<g_crlf;
		std::cout<<ostream_.str ();
		ostream_.clear();
		ostream_.str ("");
	}
	virtual	std::ostream&			get_ostream()
	{return ostream_;}
private:
	std::ostringstream			ostream_;
	bool						die_;
};

typedef	loger	ostream_loger;


/************************************************************************/
/*                                                                      */
/************************************************************************/

template<class T_>
log_warper&	append_val(log_warper& where_i,const T_& val)
{
	where_i.get_impl ().get_ostream ()<<val;
	return where_i;
}
/************************************************************************/
/*                                                                      */
/************************************************************************/
log_warper::log_warper(void):impl_(new ostream_loger())
{}

log_warper::~log_warper(void)
{
	if(impl_) delete impl_;
	impl_=NULL;
}

log_warper::log_warper(loging_level log_lvl):impl_(new ostream_loger(log_lvl))
{}
log_warper::log_warper(loging_level log_lvl,const std::string& source_file,const std::string& func_name,int line_number,int error_code)
:impl_(new ostream_loger(log_lvl,source_file,func_name,line_number,error_code))
{}
log_warper::log_warper(loging_level log_lvl,const std::string& source_file,const std::string& func_name,int line_number,bool abort)
:impl_(new ostream_loger(log_lvl,source_file,func_name,line_number,abort))
{}
log_warper&		log_warper::reset(loging_level log_lvl,const std::string& source_file,const std::string& func_name,int line_number)
{
	impl_->reset(log_lvl,source_file,func_name,line_number);
	return *this;
}
void		log_warper::finish()
{
	impl_->finish ();
}

loger&			log_warper::get_impl()
{return	*impl_;}

std::ostream& log_warper::stream()
{return impl_->get_ostream ();}

};//loging
